package com.wanmait.recycle.service.impl;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wanmait.recycle.mapper.AnswerMapper;
import com.wanmait.recycle.mapper.QuestionMapper;
import com.wanmait.recycle.pojo.Answer;
import com.wanmait.recycle.pojo.PraiseAnswer;
import com.wanmait.recycle.pojo.Userinfo;
import com.wanmait.recycle.redis.dao.RedisPraiseAnswerDao;
import com.wanmait.recycle.redis.pojo.PraiseAnswerMessage;
import com.wanmait.recycle.service.AnswerService;
import com.wanmait.recycle.service.ConfigService;
import com.wanmait.recycle.service.PraiseAnswerService;
import com.wanmait.recycle.util.PageContext;
import com.wanmait.recycle.util.Pager;

@Service
@Transactional
public class AnswerServiceImpl implements AnswerService {

	@Resource
	private AnswerMapper answerMapper;
	@Resource
	private QuestionMapper questionMapper;
	@Resource
	private RedisPraiseAnswerDao redisPraiseAnswerDao;
	@Resource
	private PraiseAnswerService praiseAnswerService;
	@Resource
	private ConfigService configService;
	
	@Override
	public void insert(Answer object) {
		// TODO Auto-generated method stub

	}

	@Override
	public void update(Answer object) {
		// TODO Auto-generated method stub

	}

	@Override
	public void delete(Integer id) {
		// TODO Auto-generated method stub

	}

	@Override
	public void delete(String ids) {
		// TODO Auto-generated method stub

	}

	@Override
	public Answer findById(Integer id) {
		// TODO Auto-generated method stub
		Answer answer = answerMapper.findByAnswerId(id);
		answer.setPraiseCount(redisPraiseAnswerDao.getCount(id));
		return answerMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<Answer> findAll() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getDataCount() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public List<Answer> findAll(Pager pager) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Answer> findAll(Answer object) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getDataCount(Answer object) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public List<Answer> findAll(Pager pager, Answer object) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void addAnswer(Answer answer) {
		// TODO Auto-generated method stub
		answerMapper.addAnswer(answer);
		questionMapper.addReplyCount(answer.getQuestion().getId());
	}

	@Override
	public void isPick(Answer answer) {
		// TODO Auto-generated method stu
		answerMapper.isPick(answer);
		questionMapper.isSolve(answer.getQuestion().getId());
	}

	//前台获得enable为1的所有回答 AD 03.13
		@Override
		public PageInfo<Answer> findEnableAnswer() {
			Map<String, Map<String,String>> config = configService.findAllConfig();
			PageHelper.startPage(PageContext.getPageNum(), Integer.parseInt(config.get("前台答案").get("webAnswer")));
			List<Answer> answers = answerMapper.findEnableAnswer();
			//从redis中获取每篇文章最新的点赞数，放入对象中
			for (Answer an : answers) {
				an.setPraiseCount(redisPraiseAnswerDao.getCount(an.getId()));
			}
			PageInfo<Answer> pageInfo = new PageInfo<Answer>(answers,7);
			
			return pageInfo;
		}

		@Override
		public Answer findByAnswerId(Integer id) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public boolean isPraise(Integer answerId, Integer userinfoId) {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public void addPraise(Integer answerId, Integer userinfoId) {
			// TODO Auto-generated method stub
			String message;
			redisPraiseAnswerDao.addPraiseAnswer(answerId, userinfoId);
			//修改总的点赞数量+1
			redisPraiseAnswerDao.increaseCount(answerId);
			
			
			message="{\"answerId\":"+answerId+",\"userinfoId\":"+userinfoId+",\"delete\":1,\"inputTime\":"+System.currentTimeMillis()+"}";
			//向队列中添加消息
			redisPraiseAnswerDao.leftPush(message);
			//userLike:update:set 哪些问题进行过点赞或者取消点赞
			redisPraiseAnswerDao.addUpdate(answerId);
		}

		@Override
		public void removePraise(Integer answerId, Integer userinfoId) {
			// TODO Auto-generated method stub
			String message;
			redisPraiseAnswerDao.removePraiseAnswer(answerId, userinfoId);
			//修改总的点赞数量-1
			redisPraiseAnswerDao.decreaseCount(answerId);
			
			message="{\"answerId\":"+answerId+",\"userinfoId\":"+userinfoId+",\"delete\":0,\"inputTime\":"+System.currentTimeMillis()+"}";
			//向队列中添加消息
			redisPraiseAnswerDao.leftPush(message);
			//userLike:update:set 哪些问题进行过点赞或者取消点赞
			redisPraiseAnswerDao.addUpdate(answerId);
		}

		/*每次从redis中取出20条消息，如果小于20条，则取完*/
		private List<String> popMessage(){
			
			List<String> messages = new ArrayList<>();
			for (int i = 0; i < 20 ; i++) {
				
				String message = redisPraiseAnswerDao.rightPop();
				if(message!=null) {
					messages.add(message);
				}else {
					break;
				}
			}
			return messages;
		}
		
		@Override
		public void processQueue() {
			// TODO Auto-generated method stub
			//点赞
			List<PraiseAnswer> insertPraiseAnswerList = new ArrayList<>();
			//取消点赞
			List<PraiseAnswer> deletePraiseAnswerList = new ArrayList<>();
			
			while(true)
			{
				
				//获取消息，每次二十条
				List<String> messages = this.popMessage();
				
				for (String message : messages) {
					
					//ObjectMapper类是Jackson库的主要类。它提供一些功能将转换成Java对象匹配JSON结构，反之亦然
					ObjectMapper objectMapper = new ObjectMapper();
					//将redis中的json格式的消息转换为PraiseAnswerMessage对象
					PraiseAnswerMessage praiseAnswerMessage;
					
					try {
						
						praiseAnswerMessage = objectMapper.readValue(message, PraiseAnswerMessage.class);
						//将解析后的各个属性的值赋给PraiseArtice
						PraiseAnswer praiseAnswer = new PraiseAnswer();
						//存文章id
						Answer answer = new Answer();
						answer.setId(praiseAnswerMessage.getAnswerId());
						praiseAnswer.setAnswer(answer);
						//存用户id
						Userinfo userinfo = new Userinfo();
						userinfo.setId(praiseAnswerMessage.getUserinfoId());
						praiseAnswer.setUserinfo(userinfo);
						//存加入时间
						praiseAnswer.setInputTime(new Timestamp(praiseAnswerMessage.getInputTime()));
						//如果isDelete为true，加入点赞。如果为false则加入取消点赞
						if(praiseAnswerMessage.isDelete()) {
							
							insertPraiseAnswerList.add(praiseAnswer);
							
						}else {
							
							deletePraiseAnswerList.add(praiseAnswer);
						}
						
					} catch (JsonParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (JsonMappingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
				
				if(insertPraiseAnswerList.size()!=0) {
					//批量点赞
					praiseAnswerService.insertBatch(insertPraiseAnswerList);
				}
				if(deletePraiseAnswerList.size()!=0) {
					//批量取消点赞
					praiseAnswerService.deleteBatch(deletePraiseAnswerList);
				}
				
				//小于20条说明队列中没有消息了
				if(messages.size()<20)
				{
					break;
				}
			}
		}

		@Override
		public void processPraiseCount() {
			// TODO Auto-generated method stub
			List<Answer> answerList = new ArrayList<>();
			Set<Integer> answerIds = redisPraiseAnswerDao.getUpdate();
			Answer answer = null;
			for (Integer answerId : answerIds) {
				answer = new Answer();
				Integer praiseCount = redisPraiseAnswerDao.getCount(answerId);
				answer.setId(answerId);
				answer.setPraiseCount(praiseCount);
				
				answerList.add(answer);
			}
			for (Answer answer1 : answerList) {
				
				answerMapper.processPraiseCount(answer1);
			}
			//redisPraiseAnswerDao.removeUpdate();
		}

		

}
